#include "gsoapserver.h"

//#include "gSoapFoundation/rosgsoapnamespace.nsmap"
#include "gSoapFoundation/rosgsoapnamespaceH.h"
using namespace rosgsoapnamespace;

//*******************************************************
pthread_mutex_t queueCs;                //队列锁
pthread_cond_t queueCv;                 //条件变量
SOAP_SOCKET queue[MAX_QUEUE];           //数组队列
int head=0, tail=0;                     //队列头队列尾初始化

void *processQueue(void *);             //线程入口函数
int enqueue(SOAP_SOCKET);               //入队列函数
SOAP_SOCKET dequeue(void);              //出队列函数

//*******************************************************
GsoapServerForRos::GsoapServerForRos()
{
}

GsoapServerForRos::~GsoapServerForRos()
{
    soap_destroy(&recieveSoap);
    soap_end(&recieveSoap);
    soap_done(&recieveSoap);
    free(&recieveSoap);
}

bool GsoapServerForRos::startServer(int port)
{
    std::cout << "startServer open1111111\n\n\n";

    soap_init(&recieveSoap);
    //recieveSoap.connect_timeout = 5;
    //recieveSoap.accept_timeout = 5;
    recieveSoap.send_timeout = 2;//超时判定
    recieveSoap.recv_timeout = 2;
    soap_set_mode(&recieveSoap,SOAP_C_UTFSTRING);//UTF-8

//    std::cout << "bind===========";
    SOAP_SOCKET m = soap_bind(&recieveSoap, NULL, port, BACKLOG);
//    std::cout << "启动失败=====m======"<<m<<"\n\n\n";
    if(m < 0)//启动失败
    {
        return false;
    }

    return true;
}

void GsoapServerForRos::loopRecvServer()
{
    //已在头文件初始化
    //struct soap *soapThread[MAX_THREAD];
    //pthread_t tid[MAX_THREAD];

    //锁和条件变量初始化
    pthread_mutex_init(&queueCs,NULL);
    pthread_cond_init(&queueCv,NULL);

//    //绑定服务端口 SOAP_SOCKET = int
//    SOAP_SOCKET m = soap_bind(&recieveSoap,"192.168.1.136",5050,BACKLOG);
//    //循环直至服务套接字合法
//    while (!soap_valid_socket(m))
//    {
//        fprintf(stderr,"Bind port error! ");
//        m = soap_bind(&recieveSoap,"192.168.1.136",5050,BACKLOG);
//    }
//    fprintf(stderr,"socket connection successful %d \n",m);

    //生成服务线程
    for(int i = 0;i<MAX_THREAD;i++)
    {
        recieveSoapThread[i] = soap_copy(&recieveSoap);
        recieveSoapThread[i]->send_timeout = 2;
        recieveSoapThread[i]->recv_timeout = 2;
        pthread_create(&tid[i],NULL,(void*(*)(void*))processQueue,(void*)recieveSoapThread[i]);
    }

    fprintf(stderr,"Starting gsoap threads !\n" );

    std::cout<<&recieveSoap<<std::endl;
    do{
        SOAP_SOCKET s = soap_accept(&recieveSoap);//等待连接
//        if(!soap_valid_socket(s))
//        {
//            std::cout<<"here3"<<std::endl;
//            if(recieveSoap.errnum)
//            {
//                soap_print_fault(&recieveSoap,stderr);
//                continue;
//            }
//            else
//            {
//                fprintf(stderr,"Server timed out \n");
//                break;
//            }

//            fprintf(stderr,"Accepted connection from IP= %d.%d.%d.%d socket = %d ",
//            ((recieveSoap.ip)>>24)&&0xFF,((recieveSoap.ip)>>16)&0xFF,((recieveSoap.ip)>>8)&0xFF,(recieveSoap.ip)&0xFF,(recieveSoap.socket));
//            //请求的套接字进入队列，如果队列已满则循环等待
//            while(enqueue(s) == SOAP_EOM)
//            sleep(1);
//        }

        if (s < 0)
        {
            soap_print_fault(&recieveSoap, stderr);
            exit(-1);
        }
//        printf("from %ld.%ld.%ld.%ld :\n",
//               ((recieveSoap.ip)>>24) & 0xFF,
//               ((recieveSoap.ip)>>16) & 0xFF,
//               ((recieveSoap.ip)>>8) & 0xFF,
//               (recieveSoap.ip) & 0xFF);
        while(enqueue(s) == SOAP_EOM){
            usleep(1000);
        }

//        soap_serve(&recieveSoap); //该句说明该server的服务
//        soap_end(&recieveSoap);

//        std::cout<<&recieveSoap<<std::endl;
    }while(1);
}

void GsoapServerForRos::quitServer()
{
    //服务结束后的清理工作
    std::cout << "quit and clean gsoapServer"<<std::endl;

    for(int i = 0; i < MAX_THREAD; i++)
    {
        while (enqueue(SOAP_INVALID_SOCKET) == SOAP_EOM)
        {
            usleep(10);
        }
    }

    fprintf(stderr,"Waiting for threads terminated!\n" );
    for(int i=0; i< MAX_THREAD; i++)
    {
        pthread_join(tid[i],NULL);
     //   fprintf(stderr,"terminated \n");

        soap_destroy( recieveSoapThread[i] );
        soap_end( recieveSoapThread[i] );
        soap_done( recieveSoapThread[i]) ;
        free( recieveSoapThread[i] );
    }
    pthread_mutex_destroy(&queueCs);
    pthread_cond_destroy(&queueCv);


    //soap_destroy(&recieveSoap);
    //soap_end(&recieveSoap);
    soap_done(&recieveSoap);
    //soap_free(&recieveSoap);//clean实例 2016.11.09存在问题
}

//线程入口函数
void * processQueue(void *soap)
{
    //printf("this thread tid = %u\n", pthread_self());
    struct soap * tsoap = (struct soap *)soap;
    for(;;)
    {
        tsoap->socket = dequeue();
        if (!soap_valid_socket(tsoap->socket))
        {
            break;
        }

//        soap_serve(tsoap);
        rosgsoapnamespace_serve(tsoap);
        soap_destroy(tsoap);
        soap_end(tsoap);
        //fprintf(stderr,"served\n");
    }
    return NULL;
}

//入队列操作
int enqueue(SOAP_SOCKET sock)
{
    int status = SOAP_OK;
    int next;
    pthread_mutex_lock(&queueCs);
    next = tail +1;
    if (next >= MAX_QUEUE)
        next = 0;
    if (next == head)
        status = SOAP_EOM;
    else
    {
        queue[tail] =sock;
        tail = next;  
        pthread_cond_signal(&queueCv);
    }
    pthread_mutex_unlock(&queueCs);
    return status;
}

//出队列操作
SOAP_SOCKET dequeue()
{
    SOAP_SOCKET sock;
    pthread_mutex_lock(&queueCs);
//    while (head == tail )
//    {
//        pthread_cond_wait(&queueCv,&queueCs);
//    }

    pthread_cond_wait(&queueCv,&queueCs);
    sock = queue[head++];
    if (head >= MAX_QUEUE)
    {
        head =0;
    }
    pthread_mutex_unlock(&queueCs);
    return sock;
}
